package com.yunji.base.business;

import com.yunji.base.dto.UserDTO;
import com.yunji.base.vo.UserInfoVO;
import com.yunji.common.base.BaseBusiness;
import com.yunji.common.constant.LogicCode;
import com.yunji.common.enums.common.UserType;
import com.yunji.common.model.domain.SysRoleDO;
import com.yunji.common.model.domain.SysUserDO;
import com.yunji.common.model.dto.LoginInfo;
import com.yunji.common.model.vo.RoleVo;
import com.yunji.common.utils.SecurityUtils;
import com.yunji.common.utils.StringUtils;
import com.yunji.common.utils.bean.BeanUtils;
import com.yunji.system.context.SystemContext;
import com.yunji.system.service.ISysRoleService;
import com.yunji.system.service.ISysUserService;
import com.yunji.system.service.TokenService;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @version 1.0
 * @Project: yunji-coffee
 * @Package com.yunji.user.business
 * @FileName MultiUserBusiness.java
 * @Copyright Copyright © 2024 云集互联. All Rights Reserved
 * Company		com
 * @CreateTime 2024-08-17 15:32:14
 * @Description 多用户业务处理
 * @Modification Author                    History Time			Version				Description
 * --------------------------------------------------------------------------------
 * HuaAo0803@163.com	2024-08-17 15:32:14		1.0					1.0 Version
 * @since JDK 1.8.0_202
 */
@Component
public class MultiUserBusiness extends BaseBusiness {
    @Resource
    ISysUserService userService;

    @Resource
    ISysRoleService roleService;

    @Resource
    TokenService tokenService;


    private static final String CREATE_ERROR_USERNAME = "新增用户'{}'失败，登录账号已存在";
    private static final String UPDATE_ERROR_USERNAME = "修改用户'{}'失败，手机号码已存在";

    /**
     * @param user 用户信息参数
     * @return List<SysUser> 用户信息列表
     * @Title search
     * @Intro 查询用户信息列表
     * @Date 2024-08-20 14:59:24.031
     */
    public List<SysUserDO> search(SysUserDO user) {
        LoginInfo login = tokenService.getUser();

        String userType = user.getUserType();
        String text = UserType.getText(userType);
        Long belongId = login.getBelongId();
        logs.info("【用户列表】用户类型={}:{},所属ID:{}", userType, text, belongId);
        user.setBelongId(belongId);
        user.setMainAccount(LogicCode.NO);
        List<SysUserDO> users = userService.searchUserList(user);
        Long[] userIds = users.stream().map(SysUserDO::getUserId).toArray(Long[]::new);
        List<RoleVo> roles = roleService.selectRolesByUserIds(userIds);
        if (BeanUtils.isNotNull(roles)) {
            Map<Long, List<SysRoleDO>> map = new HashMap<>();
            roles.forEach(r -> map.computeIfAbsent(r.getUserId(), k -> new ArrayList<>()).add(r));
            users.forEach(u -> u.setRoles(map.getOrDefault(u.getUserId(), null)));
        }
        return users;
    }

    /**
     * @param userId 用户信息ID
     * @return UserInfoVO 用户信息详情
     * @Title select
     * @Intro 获取用户信息详情
     * @Date 2024-08-20 14:59:24.031
     */
    public UserInfoVO select(Long userId) {
        logs.info("【用户详情】用户ID:{}", userId);
        UserInfoVO vo = new UserInfoVO();
        List<SysRoleDO> roles = roleService.selectRoleAll();
        Assert.isTrue(BeanUtils.isNotNull(roles), "未找到角色信息");

        vo.setRoles(SysUserDO.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
        if (StringUtils.isNull(userId)) {
            return vo;
        }

        SysUserDO user = userService.selectUserById(userId);
        vo.setUser(user);
        List<SysRoleDO> list = user.getRoles();
        if (BeanUtils.isNull(list)) {
            return vo;
        }
        vo.setRoleIds(list.stream().map(SysRoleDO::getRoleId).collect(Collectors.toList()));
        return vo;
    }

    /**
     * @param user 用户信息
     * @Title create
     * @Intro 创建用户信息
     * @Date 2024-08-20 14:59:24.031
     */
    @Transactional
    public Long create(UserDTO user) {
        String nickname = user.getNickName();
        String phone = user.getPhonenumber();
        logs.info("【创建用户】用户昵称:{},手机号码:{}", nickname, phone);

        Assert.isTrue(BeanUtils.isNotNull(nickname), "请输入用户昵称信息");
        Assert.isTrue((BeanUtils.isNotNull(phone) && phone.matches("^1\\d{10}$")), "请输入正确的手机号码");


        String password = user.getPassword();
        if (BeanUtils.isNull(password)) {
            String initPassword = phone.substring(phone.length() - 6);
            logs.info("【创建用户】初始密码:{}", initPassword);
            user.setPassword(initPassword);
        }

        LoginInfo login = tokenService.getUser();
        String userType = login.getUserType();
        Long belongId = login.getBelongId();
        logs.info("【创建用户】当前登录用户类型:{},所属信息ID:{}", userType, belongId);

        SysUserDO checkUser = new SysUserDO();
        checkUser.setUserName(phone);
        Assert.isTrue(userService.checkUserNameUnique(checkUser), StringUtils.format(CREATE_ERROR_USERNAME, phone));

        SysUserDO create = new SysUserDO();
        BeanUtils.clone(user, create);
        create.setUserName(phone);
        create.setMainAccount(LogicCode.NO);
        create.setBelongId(belongId);
        create.setUserType(userType);
        create.setPhonenumber(phone);
        create.setCreateBy(SystemContext.getUsername());
        create.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
        Assert.isTrue((userService.insertUser(create) > 0), "新增失败");

        return create.getUserId();
    }

    /**
     * @param user 用户信息
     * @Title update
     * @Intro 更新用户信息
     * @Date 2024-08-20 14:59:24.031
     */
    @Transactional
    public void update(UserDTO user) {
        Long userId = user.getUserId();
        String phone = user.getPhonenumber();
        logs.info("【修改用户】用户ID:{},手机号码:{}", userId, phone);

        Assert.isTrue(BeanUtils.isNotNull(userId), "未找到用户信息");
        SysUserDO update = new SysUserDO();
        BeanUtils.clone(user, update);

        Assert.isTrue((BeanUtils.isNotNull(phone) && phone.matches("^1\\d{10}$")), "请输入正确的手机号码");
        update.setUserName(phone);

        userService.checkUserAllowed(update);

        Assert.isTrue((userService.checkUserNameUnique(update)), StringUtils.format(UPDATE_ERROR_USERNAME, phone));

        update.setMainAccount(LogicCode.NO);
        update.setUpdateBy(SystemContext.getUsername());
        Assert.isTrue((userService.updateUser(update) > 0), "修改失败");
    }

    /**
     * @param ids 用户信息ID数组
     * @Title delete
     * @Intro 删除用户信息
     * @Date 2024-08-20 14:59:24.031
     */
    public void delete(Long... ids) {
        Assert.isTrue(!ArrayUtils.contains(ids, SystemContext.getUserId()), "当前用户不能删除");
        Assert.isTrue((userService.deleteUserByIds(ids) > 0), "删除失败");
    }
}